package util.concurrent;

import org.junit.Test;

import java.util.Random;
import java.util.concurrent.*;

public class Many {

    @Test
    public  void test1() throws InterruptedException {
        //强调的是多个线程互相等待完成，才去做某个事情，可以重置。
        CyclicBarrier cyclicBarrier = new CyclicBarrier(3, () -> {
            System.out.println("搬来一箱红牛庆祝--------(所有线程完成后要做的事情)");
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        for (int i = 1; i <= 3; i++) {
            new Thread(() -> {
                try {
                    TimeUnit.SECONDS.sleep(1);
                    System.out.println(Thread.currentThread().getName() + " 跑到了终点");
                    cyclicBarrier.await();
                    System.out.println(Thread.currentThread().getName() + " 开一瓶红牛");
                } catch (InterruptedException | BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }).start();
        }

        Thread.currentThread().join();
    }


    public static void test2() {
        CountDownLatch countDownLatch = new CountDownLatch(2);
        for (int i = 0; i <2; i++) {
            int finalI = i;
            new Thread(() -> {
                try {
                    System.out.println(finalI + "一个人走向起点");
                    countDownLatch.await();
                    System.out.println(Thread.currentThread().getName() + "大家一起run");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();

            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
            }
            countDownLatch.countDown();
        }
       /* try {
            Thread.currentThread().join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }*/

    }

    @Test
    public  void test2多线程程版本() throws InterruptedException {
        int count = 30;
        CountDownLatch countDownLatch = new CountDownLatch(count);
        for (int i = 1; i <=count; i++) {
            int finalI = i;
            new Thread(() -> {
                try {
                    int sleepTime = 1000 + new Random().nextInt(5000);
                    Thread.sleep(sleepTime);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println(finalI + "一个人走向起点");
                countDownLatch.countDown();
            }).start();
        }

        countDownLatch.await();
        System.out.printf("一起做某事");
    }

    @Test
    public  void test2线程池版本() throws InterruptedException {
        int count = 30;
        ThreadPoolExecutor executor = new ThreadPoolExecutor(count, count, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<>(100));
        executor.setRejectedExecutionHandler(new ThreadPool.Policy());

        CountDownLatch countDownLatch = new CountDownLatch(count);
        for (int i = 1; i <= count; i++) {
            int finalI = i;
            executor.execute(()->{
                try {
                    int sleepTime = 1000 + new Random().nextInt(5000);
                    Thread.sleep(sleepTime);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println(finalI + "一个人走向起点");
                countDownLatch.countDown();
            });

        }

        countDownLatch.await();
        System.out.printf("一起做某事");
    }

    @Test
    public  void test3() throws InterruptedException {
        //可以控同时访问的线程个数
        Semaphore semaphore = new Semaphore(3);
        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                try {
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName() + "获取许可");
                    try {
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    System.out.println(Thread.currentThread().getName() + " 释放许可");
                    semaphore.release();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }
        Thread.sleep(10000L);

    }

}
